package alp.starcode.sanping.dataapply.service;

import alp.starcode.common.base.exception.OperateException;
import alp.starcode.common.base.exception.ParamsNullException;
import alp.starcode.common.mybatis.page.Pagination;
import alp.starcode.common.mybatis.sort.Sorter;
import alp.starcode.common.mybatis.util.PageBeanUtil;
import alp.starcode.sanping.dataapply.model.dto.MapDataDTO;
import alp.starcode.sanping.dataapply.model.vo.MapDataVO;
import alp.starcode.sanping.framework.base.BaseService;
import alp.starcode.sanping.framework.database.mariadb.mybatis.dao.MapDataDao;
import alp.starcode.sanping.framework.database.mariadb.mybatis.entity.Information;
import alp.starcode.sanping.framework.database.mariadb.mybatis.entity.MapData;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;

/**
 * TODO
 *
 * @author wujie
 * @date 2024/3/14 17:32
 */
@Service
public class MapDataService extends BaseService {

    @Autowired
    MapDataDao mapDataDao;

    /**
     * 分页查询信息
     *
     * @param pagination    分页对象
     * @param searchKeyword 搜索关键字
     * @param sorters       排序字段
     * @return 分页对象
     */
    public Pagination<MapDataVO> pageList(Pagination<MapData> pagination, Double minRatio, Double maxRatio, String searchKeyword, Sorter sorters) {
        MPJLambdaWrapper<MapData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(MapData.class);
        // 搜索关键字
        if (StringUtils.isNotEmpty(searchKeyword)) {
            queryWrapper.and(qw -> qw.or().like(MapData::getProvince, searchKeyword)
                    .or().like(MapData::getCityName, searchKeyword));
        }
        if(null != minRatio) {
            queryWrapper.ge(MapData::getTsgyRatio, minRatio);
        }
        if(null != maxRatio) {
            queryWrapper.le(MapData::getTsgyRatio, maxRatio);
        }

        // 有效数据
        //构建排序条件
        sorters.sort(queryWrapper);
        //分页查询数据，并构建返回对象
        return PageBeanUtil.copyProperties(mapDataDao.page(pagination, queryWrapper), MapDataVO.class);
    }

    /**
     * 查询地图信息
     *
     * @param province 搜索关键字
     * @param cityType 搜索关键字
     * @param industryType 搜索关键字
     * @param minRatio 搜索关键字
     * @param maxRatio 搜索关键字
     * @param sorters       排序字段
     * @return 分页对象
     */
    public JSONArray getTypeDate(String province, String cityType, String industryType, Double minRatio, Double maxRatio, Sorter sorters) {
        MPJLambdaWrapper<MapData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.select(MapData::getCityName, MapData::getProvince, MapData::getId, MapData::getGsqyNum, MapData::getCyType);
        queryWrapper.select("sum(gsqy_num) as gsqyNum, sum(zcz_amount) as zczAmount, sum(tsgy_ratio) as tsgyRatio");
        // 搜索关键字
        if (StringUtils.isNotEmpty(province)) {
            queryWrapper.like(MapData::getProvince, province);
        }
        if (StringUtils.isNotEmpty(cityType)) {
            queryWrapper.like(MapData::getCityType, cityType);
        }
        if (StringUtils.isNotEmpty(industryType)) {
            queryWrapper.like(MapData::getCyType, industryType);
        }
        if(null != minRatio) {
            queryWrapper.ge(MapData::getTsgyRatio, minRatio);
        }
        if(null != maxRatio) {
            queryWrapper.le(MapData::getTsgyRatio, maxRatio);
        }
        queryWrapper.groupBy(MapData::getProvince, MapData::getCityName);

        //构建排序条件
        sorters.sort(queryWrapper);
        //查询数据，并构建返回对象
        List<MapData> list = mapDataDao.list(queryWrapper);
        JSONArray jsonArray = new JSONArray();
        Map<String, List<MapData>> proviceMap = new HashMap<>();

        // 按省分组
        for(MapData mapData : list) {
            String provinceItem = mapData.getProvince();
            if(!proviceMap.containsKey(provinceItem)) {
                proviceMap.put(provinceItem, new ArrayList<>());
            }
            proviceMap.get(provinceItem).add(mapData);
        }
        // 封装数据
        for (Map.Entry<String, List<MapData>> entry : proviceMap.entrySet()) {

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("proviceName", entry.getKey());
            jsonObject.put("proviceId", entry.getKey());

            JSONArray cityArr = new JSONArray();
            double provinceTotalOutputValue = 0;
            for(MapData mapData : entry.getValue()) {
                JSONObject cityObj = new JSONObject();
                cityObj.put("label", mapData.getCityName());
                cityObj.put("enterprisesCount", mapData.getGsqyNum());
                cityObj.put("totalOutputValue", getFixNum(Double.valueOf(mapData.getZczAmount())));
                cityObj.put("proportion", mapData.getTsgyRatio());
                cityArr.add(cityObj);

                provinceTotalOutputValue += Double.valueOf(mapData.getZczAmount());
            }
            // 保留两位小数点

            jsonObject.put("provinceTotalOutputValue", getFixNum(provinceTotalOutputValue));
            jsonObject.put("provinceData", cityArr);
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }

    /**
     * 保留两位小数点
     * @return
     */
    public double getFixNum(double num) {
        double value = 0;
        try {
            DecimalFormat df = new DecimalFormat("#.00");
            String formattedNumber = df.format(num);
            value = Double.parseDouble(formattedNumber);
        } catch (Exception e) {
            return value;
        }
        return value;
    }

    /**
     * 根据Id获取信息
     *
     * @param id 主键Id
     * @return Role
     */
    public MapDataVO getById(String id) {
        if (id == null || id.isEmpty()) {
            throw new ParamsNullException("[id]不能为空！");
        }
        MPJLambdaWrapper<MapData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(MapData.class);
        queryWrapper.eq(MapData::getId, id);
        // 有效数据
        MapData entity = mapDataDao.getOne(queryWrapper);
        return BeanUtil.copyProperties(entity, MapDataVO.class);
    }

    /**
     * 添加数据
     *
     * @param entityDTO 参数对象
     */
    public void add(MapDataDTO entityDTO) {
        // 进行数据转换
        MapData entity = entityDTO.converter();
        // 生成流水号
        String uuid = UUID.randomUUID().toString();
        // 判断数据是否新增成功，失败抛出异常提示。
        if (!mapDataDao.save(entity)) {
            throw new OperateException("数据添加失败，写入数据异常：[%s]", entity);
        }
    }

    /**
     * 删除数据
     *
     * @param entityDTO 参数对象
     */
    public void delete(MapDataDTO entityDTO) {
        MapData entity = new MapData();
        entity.setId(entityDTO.getId());
        if (!mapDataDao.updateById(entity)) {
            throw new OperateException("数据删除失败，写入数据异常：[%s]", entity);
        }
    }

    /**
     * 修改数据
     *
     * @param entityDTO 参数对象
     */
    public void update(MapDataDTO entityDTO) {
        MapData entity = entityDTO.converter();
        //角色KEY不允许修改，避免产生脏数据
        if (!mapDataDao.updateById(entity)) {
            throw new OperateException("数据修改失败，写入数据异常：[%s]", entity);
        }
    }

    /**
     * 获取产业类型
     *
     * @return Role
     */
    public List<MapData> getCyType() {
        MPJLambdaWrapper<MapData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.select(MapData::getCyType);
        queryWrapper.groupBy(MapData::getCyType);
        // 有效数据
        return mapDataDao.list(queryWrapper);
    }

    /**
     * 获取行业类型
     *
     */
    public List<MapData> getIndustryType() {
        MPJLambdaWrapper<MapData> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(MapData.class);
        // 有效数据
        queryWrapper.groupBy(MapData::getCyType);
        return mapDataDao.list(queryWrapper);
    }

}
